﻿//using System;
//using System.Collections.Generic;
//using System.Collections.Specialized;
//using System.Configuration;
//using System.Linq;
//using System.Web.Hosting;
//using System.Web.Mvc;
//using System.Web.Profile;

//using ApplicationBoilerplate.DataProvider;

//using MongoDB.Bson;
//using MongoDB.Driver;
//using MongoDB.Driver.Builders;

//namespace MVCBootstrap.MongoDB.Web.Security {

//    /// <summary>
//    /// 
//    /// </summary>
//    /// <remarks>Code heavily inspired by the MongoDB.Web project on GitHub</remarks>
//    public class MongoDBProfileProvider : ProfileProvider {

//        private MongoCollection ProfileCollection {
//            get {
//                return ((Context)DependencyResolver.Current.GetService<IContext>()).GetCollection("profile");
//            }
//        }

//        public override String ApplicationName { get; set; }

//        public override Int32 DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) {
//            IMongoQuery query = Query.And(Query.EQ("ApplicationName", this.ApplicationName), Query.LTE("LastActivityDate", userInactiveSinceDate));

//            if (authenticationOption != ProfileAuthenticationOption.All) {
//                query = Query.And(query, Query.EQ("IsAnonymous", authenticationOption == ProfileAuthenticationOption.Anonymous));
//            }

//            return (Int32)this.ProfileCollection.Remove(query).DocumentsAffected;
//        }

//        public override Int32 DeleteProfiles(String[] usernames) {
//            IMongoQuery query = Query.And(Query.EQ("ApplicationName", this.ApplicationName), Query.In("Username", new BsonArray(usernames)));
//            return (Int32)this.ProfileCollection.Remove(query).DocumentsAffected;
//        }

//        public override Int32 DeleteProfiles(ProfileInfoCollection profiles) {
//            return this.DeleteProfiles(profiles.Cast<ProfileInfo>().Select(profile => profile.UserName).ToArray());
//        }

//        public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) {
//            return GetProfiles(authenticationOption, usernameToMatch, userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
//        }

//        public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) {
//            return GetProfiles(authenticationOption, usernameToMatch, null, pageIndex, pageSize, out totalRecords);
//        }

//        public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) {
//            return GetProfiles(authenticationOption, null, userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
//        }

//        public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) {
//            return GetProfiles(authenticationOption, null, null, pageIndex, pageSize, out totalRecords);
//        }

//        public override Int32 GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) {
//            IMongoQuery query = GetQuery(authenticationOption, null, userInactiveSinceDate);
//            return (Int32)this.ProfileCollection.Count(query);
//        }

//        public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection) {
//            SettingsPropertyValueCollection settingsPropertyValueCollection = new SettingsPropertyValueCollection();

//            if (context == null || collection == null || collection.Count < 1) {
//                return settingsPropertyValueCollection;
//            }

//            String username = (String)context["UserName"];

//            if (String.IsNullOrWhiteSpace(username)) {
//                return settingsPropertyValueCollection;
//            }

//            IMongoQuery query = Query.And(Query.EQ("ApplicationName", this.ApplicationName), Query.EQ("Username", username));
//            BsonDocument bsonDocument = this.ProfileCollection.FindOneAs<BsonDocument>(query);
//            if (bsonDocument == null) {
//                bsonDocument = new BsonDocument {
//                    { "ApplicationName", this.ApplicationName },
//                    { "Username", username }
//                };
//                bsonDocument = this.ProfileCollection.Insert<BsonDocument>(bsonDocument).Response;
//            }

//            foreach (SettingsProperty settingsProperty in collection) {
//                SettingsPropertyValue settingsPropertyValue = new SettingsPropertyValue(settingsProperty);
//                settingsPropertyValueCollection.Add(settingsPropertyValue);

//                Object value = bsonDocument[settingsPropertyValue.Name].RawValue;

//                if (value != null) {
//                    settingsPropertyValue.PropertyValue = value;
//                    settingsPropertyValue.IsDirty = false;
//                    settingsPropertyValue.Deserialized = true;
//                }
//            }

//            UpdateBuilder update = Update.Set("LastActivityDate", DateTime.Now);
//            this.ProfileCollection.Update(query, update);

//            return settingsPropertyValueCollection;
//        }

//        public override void Initialize(String name, NameValueCollection config) {
//            this.ApplicationName = config["applicationName"] ?? HostingEnvironment.ApplicationVirtualPath;
//            base.Initialize(name, config);
//        }

//        public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) {
//            String username = (String)context["UserName"];
//            Boolean isAuthenticated = (Boolean)context["IsAuthenticated"];

//            if (String.IsNullOrWhiteSpace(username) || collection.Count < 1) {
//                return;
//            }

//            Dictionary<String, Object> values = new Dictionary<String, Object>();

//            foreach (SettingsPropertyValue settingsPropertyValue in collection) {
//                if (!settingsPropertyValue.IsDirty) {
//                    continue;
//                }

//                if (!isAuthenticated && !(bool)settingsPropertyValue.Property.Attributes["AllowAnonymous"]) {
//                    continue;
//                }

//                values.Add(settingsPropertyValue.Name, settingsPropertyValue.PropertyValue);
//            }

//            IMongoQuery query = Query.And(Query.EQ("ApplicationName", this.ApplicationName), Query.EQ("Username", username));
//            BsonDocument bsonDocument = this.ProfileCollection.FindOneAs<BsonDocument>(query);

//            if (bsonDocument == null) {
//                bsonDocument = new BsonDocument {
//                    { "ApplicationName", this.ApplicationName },
//                    { "Username", username }
//                };
//            }

//            BsonDocument mergeDocument = new BsonDocument {
//                { "LastActivityDate", DateTime.Now },
//                { "LastUpdatedDate", DateTime.Now }
//            };

//            mergeDocument.Add(values as IDictionary<string, object>);
//            bsonDocument.Merge(mergeDocument);

//            this.ProfileCollection.Save(bsonDocument);
//        }

//        #region Private Methods

//        private ProfileInfoCollection GetProfiles(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime? userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) {
//            IMongoQuery query = GetQuery(authenticationOption, usernameToMatch, userInactiveSinceDate);

//            totalRecords = (Int32)this.ProfileCollection.Count(query);

//            ProfileInfoCollection profileInfoCollection = new ProfileInfoCollection();

//            foreach (BsonDocument bsonDocument in this.ProfileCollection.FindAs<BsonDocument>(query).SetSkip(pageIndex * pageSize).SetLimit(pageSize)) {
//                profileInfoCollection.Add(ToProfileInfo(bsonDocument));
//            }

//            return profileInfoCollection;
//        }

//        private IMongoQuery GetQuery(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime? userInactiveSinceDate) {
//            var query = Query.EQ("ApplicationName", this.ApplicationName);

//            if (authenticationOption != ProfileAuthenticationOption.All) {
//                query = Query.And(query, Query.EQ("IsAnonymous", authenticationOption == ProfileAuthenticationOption.Anonymous));
//            }

//            if (!String.IsNullOrWhiteSpace(usernameToMatch)) {
//                query = Query.And(query, Query.Matches("Username", usernameToMatch));
//            }

//            if (userInactiveSinceDate.HasValue) {
//                query = Query.And(query, Query.LTE("LastActivityDate", userInactiveSinceDate));
//            }

//            return query;
//        }

//        private static ProfileInfo ToProfileInfo(BsonDocument bsonDocument) {
//            return new ProfileInfo(bsonDocument["Username"].AsString, bsonDocument["IsAnonymous"].AsBoolean, bsonDocument["LastActivityDate"].AsDateTime, bsonDocument["LastUpdatedDate"].AsDateTime, 0);
//        }

//        #endregion
//    }
//}